package club.bigtian.statusbar;

import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import lombok.Data;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.lang.reflect.Type;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * Token配置管理类
 * 从tokens.json文件加载token数据
 */
public class TokenConfig {

    // 当前使用的账户信息（单例）
    private static TokenRawData currentAccount = null;
    
    /**
     * Portal信息
     * 支持 snake_case 和 camelCase 两种命名格式
     */
    @Data
    public static class PortalInfo {
        @SerializedName(value = "credits_balance", alternate = {"creditsBalance"})
        private Integer creditsBalance;

        @SerializedName(value = "expiry_date", alternate = {"expiryDate"})
        private String expiryDate;
    }

    /**
     * Token原始数据模型（从JSON文件读取）
     * 支持 snake_case 和 camelCase 两种命名格式
     */
    @Data
    public static class TokenRawData {
        @SerializedName(value = "access_token", alternate = {"accessToken"})
        private String accessToken;

        @SerializedName(value = "auth_session", alternate = {"authSession"})
        private String authSession;

        @SerializedName(value = "ban_status", alternate = {"banStatus"})
        private String banStatus;

        @SerializedName(value = "created_at", alternate = {"createdAt"})
        private String createdAt;

        @SerializedName(value = "email_note", alternate = {"emailNote"})
        private String emailNote;

        @SerializedName(value = "id")
        private String id;

        @SerializedName(value = "portal_info", alternate = {"portalInfo"})
        private PortalInfo portalInfo;

        @SerializedName(value = "portal_url", alternate = {"portalUrl"})
        private String portalUrl;

        @SerializedName(value = "skip_check", alternate = {"skipCheck"})
        private Boolean skipCheck;

        @SerializedName(value = "tenant_url", alternate = {"tenantUrl"})
        private String tenantUrl;

        @SerializedName(value = "updated_at", alternate = {"updatedAt"})
        private String updatedAt;
    }


    
    /**
     * 尝试从配置文件加载token数据
     * 路径与 Tauri 的 app_data_dir() 保持一致
     * macOS: ~/Library/Application Support/com.cubezhao.atm/tokens.json
     * Linux: ~/.local/share/atm/tokens.json
     * Windows: C:\Users\<user>\AppData\Roaming\com.cubezhao.atm\tokens.json
     */
    public static List<TokenRawData> tryLoadTokens() {
        try {
            Path configPath = getConfigPath();
            File configFile = configPath.toFile();

            if (!configFile.exists()) {
                System.out.println("⚠️ Token配置文件不存在: " + configPath);
                return new ArrayList<>();
            }

            // 读取JSON文件
            try (FileReader reader = new FileReader(configFile)) {
                Gson gson = new Gson();
                Type listType = new TypeToken<List<TokenRawData>>(){}.getType();
                List<TokenRawData> rawTokens = gson.fromJson(reader, listType);

                if (rawTokens != null && !rawTokens.isEmpty()) {
                    System.out.println("✅ 成功加载 " + rawTokens.size() + " 个token配置");
                    return rawTokens;
                } else {
                    System.out.println("⚠️ Token配置文件为空");
                    return new ArrayList<>();
                }
            }
        } catch (Exception e) {
            System.err.println("❌ 加载token配置失败: " + e.getMessage());
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

    /**
     * 保存token数据到配置文件
     */
    public static void saveTokens(List<TokenRawData> tokens) {
        try {
            Path configPath = getConfigPath();
            File configFile = configPath.toFile();

            // 确保父目录存在
            File parentDir = configFile.getParentFile();
            if (!parentDir.exists()) {
                parentDir.mkdirs();
            }

            // 写入JSON文件
            try (FileWriter writer = new FileWriter(configFile)) {
                // 使用默认 Gson，@SerializedName 的 value 已设置为 snake_case 格式
                Gson gson = new com.google.gson.GsonBuilder()
                        .setPrettyPrinting()
                        .create();
                gson.toJson(tokens, writer);
                System.out.println("✅ 成功保存 " + tokens.size() + " 个token配置（snake_case 格式）");
            }
        } catch (Exception e) {
            System.err.println("❌ 保存token配置失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 获取配置文件路径
     * 根据不同平台构造应用数据目录
     * macOS: ~/Library/Application Support/com.cubezhao.atm
     * Linux: ~/.local/share/atm
     * Windows: C:\Users\<user>\AppData\Roaming\com.cubezhao.atm
     */
    private static Path getConfigPath() {
        String os = System.getProperty("os.name").toLowerCase();
        String userHome = System.getProperty("user.home");

        if (os.contains("mac")) {
            // macOS: ~/Library/Application Support/com.cubezhao.atm
            return Paths.get(userHome, "Library", "Application Support",
                           "com.cubezhao.atm", "tokens.json");
        } else if (os.contains("linux")) {
            // Linux: ~/.local/share/atm
            return Paths.get(userHome, ".local", "share",
                           "atm", "tokens.json");
        } else if (os.contains("win")) {
            // Windows: C:\Users\<user>\AppData\Roaming\com.cubezhao.atm
            String appData = System.getenv("APPDATA");
            if (appData != null) {
                return Paths.get(appData, "com.cubezhao.atm", "tokens.json");
            } else {
                return Paths.get(userHome, "AppData", "Roaming",
                               "com.cubezhao.atm", "tokens.json");
            }
        } else {
            // 默认路径
            return Paths.get(userHome, ".atm", "tokens.json");
        }
    }

    /**
     * 获取设置配置文件路径
     */
    private static Path getSettingsPath() {
        String os = System.getProperty("os.name").toLowerCase();
        String userHome = System.getProperty("user.home");

        if (os.contains("mac")) {
            return Paths.get(userHome, "Library", "Application Support",
                           "com.cubezhao.atm", "settings.json");
        } else if (os.contains("linux")) {
            return Paths.get(userHome, ".local", "share",
                           "atm", "settings.json");
        } else if (os.contains("win")) {
            String appData = System.getenv("APPDATA");
            if (appData != null) {
                return Paths.get(appData, "com.cubezhao.atm", "settings.json");
            } else {
                return Paths.get(userHome, "AppData", "Roaming",
                               "com.cubezhao.atm", "settings.json");
            }
        } else {
            return Paths.get(userHome, ".atm", "settings.json");
        }
    }

    /**
     * 设置配置类
     */
    @Data
    public static class Settings {
        @SerializedName("countdownSeconds")
        private Integer countdownSeconds = 300; // 默认5分钟
    }

    /**
     * 保存设置
     */
    public static void saveSettings(Settings settings) {
        try {
            Path settingsPath = getSettingsPath();
            File settingsFile = settingsPath.toFile();

            // 确保父目录存在
            File parentDir = settingsFile.getParentFile();
            if (!parentDir.exists()) {
                parentDir.mkdirs();
            }

            // 写入JSON文件
            try (FileWriter writer = new FileWriter(settingsFile)) {
                Gson gson = new com.google.gson.GsonBuilder()
                        .setPrettyPrinting()
                        .create();
                gson.toJson(settings, writer);
                System.out.println("✅ 设置已保存: 倒计时=" + settings.getCountdownSeconds() + "秒");
            }
        } catch (Exception e) {
            System.err.println("❌ 保存设置失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 加载设置
     */
    public static Settings loadSettings() {
        try {
            Path settingsPath = getSettingsPath();
            File settingsFile = settingsPath.toFile();

            if (!settingsFile.exists()) {
                System.out.println("⚠️ 设置文件不存在，使用默认值");
                return new Settings();
            }

            // 读取JSON文件
            try (FileReader reader = new FileReader(settingsFile)) {
                Gson gson = new Gson();
                Settings settings = gson.fromJson(reader, Settings.class);

                if (settings != null) {
                    System.out.println("✅ 成功加载设置: 倒计时=" + settings.getCountdownSeconds() + "秒");
                    return settings;
                } else {
                    System.out.println("⚠️ 设置文件为空，使用默认值");
                    return new Settings();
                }
            }
        } catch (Exception e) {
            System.err.println("❌ 加载设置失败: " + e.getMessage());
            e.printStackTrace();
            return new Settings();
        }
    }

    /**
     * 获取当前使用的账户信息
     */
    public static TokenRawData getCurrentAccount() {
        if (currentAccount == null) {
            // 尝试从缓存文件加载
            loadCurrentAccountFromCache();
        }
        return currentAccount;
    }

    /**
     * 设置当前使用的账户信息
     */
    public static void setCurrentAccount(TokenRawData account) {
        currentAccount = account;
        // 保存到缓存文件
        saveCurrentAccountToCache(account);
        System.out.println("✅ 已记录当前账户: " + extractDomain(account.getTenantUrl()));
    }

    /**
     * 从缓存文件加载当前账户信息
     */
    private static void loadCurrentAccountFromCache() {
        try {
            Path cachePath = getCurrentAccountCachePath();
            File cacheFile = cachePath.toFile();

            if (cacheFile.exists()) {
                try (FileReader reader = new FileReader(cacheFile)) {
                    Gson gson = new Gson();
                    currentAccount = gson.fromJson(reader, TokenRawData.class);
                    if (currentAccount != null) {
                        System.out.println("✅ 从缓存加载当前账户: " + extractDomain(currentAccount.getTenantUrl()));
                    }
                }
            }
        } catch (Exception e) {
            System.err.println("⚠️ 加载当前账户缓存失败: " + e.getMessage());
        }
    }

    /**
     * 保存当前账户信息到缓存文件
     */
    private static void saveCurrentAccountToCache(TokenRawData account) {
        try {
            Path cachePath = getCurrentAccountCachePath();
            File cacheFile = cachePath.toFile();

            // 确保目录存在
            File parentDir = cacheFile.getParentFile();
            if (parentDir != null && !parentDir.exists()) {
                parentDir.mkdirs();
            }

            // 保存JSON
            try (FileWriter writer = new FileWriter(cacheFile)) {
                Gson gson = new Gson();
                gson.toJson(account, writer);
                System.out.println("✅ 已保存当前账户到缓存");
            }
        } catch (Exception e) {
            System.err.println("⚠️ 保存当前账户缓存失败: " + e.getMessage());
        }
    }

    /**
     * 获取当前账户缓存文件路径
     */
    private static Path getCurrentAccountCachePath() {
        String os = System.getProperty("os.name").toLowerCase();
        String userHome = System.getProperty("user.home");

        if (os.contains("mac")) {
            return Paths.get(userHome, "Library", "Application Support",
                           "com.cubezhao.atm", "current_account.json");
        } else if (os.contains("linux")) {
            return Paths.get(userHome, ".local", "share",
                           "atm", "current_account.json");
        } else if (os.contains("win")) {
            String appData = System.getenv("APPDATA");
            if (appData != null) {
                return Paths.get(appData, "com.cubezhao.atm", "current_account.json");
            } else {
                return Paths.get(userHome, "AppData", "Roaming",
                               "com.cubezhao.atm", "current_account.json");
            }
        } else {
            return Paths.get(userHome, ".atm", "current_account.json");
        }
    }

    /**
     * 从URL提取域名
     */
    private static String extractDomain(String url) {
        if (url == null || url.isEmpty()) {
            return "未知域名";
        }
        try {
            String domain = url.replaceAll("^https?://", "");
            domain = domain.split("/")[0];
            return domain;
        } catch (Exception e) {
            return url;
        }
    }
}

